﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace Textbox
{
    public partial class ExtendedTextbox : TextBox
    {
        private int iNoOfDecimals = 0;
        private bool bAllowNegatives = false;
        private bool bIsDecimalPlaced = false;
        private bool bAllowSpaces = false;
        private TypeOfTextbox tTextboxType = TypeOfTextbox.All; 

        public enum TypeOfTextbox : byte
        {
            LettersOnly,
            NumbersOnly,
            All
        }

        [Description("Sets the type of textbox. e.g. Whether it allow only letters, only numbers or all."), Category("Advanced Behavior"), Browsable(true)]
        public TypeOfTextbox TextboxType
        {
            get { return tTextboxType; }
            set { tTextboxType = value; }
        }

        [Description("Sets the number of decimal places the textbox will round to when focus leaves the textbox. Only applicable for numbers only mode."), Category("Number Options"), Browsable(true)]
        public int NoOfDecimals
        {
            get { return iNoOfDecimals; }
            set { iNoOfDecimals = value; }
        }

        [Description("Sets whether the textbox allows negative numbers to be entered into the textbox. Only applicable for numbers only mode."), Category("Number Options"), Browsable(true)]
        public bool AllowNegitives
        {
            get { return bAllowNegatives; }
            set { bAllowNegatives = value; }
        }

        [Description("Sets whether the textbox allows spaces to be entered into the textbox. Only applicable for letters only mode."), Category("Letter Options"), Browsable(true)]
        public bool AllowSpaces
        {
            get { return bAllowSpaces; }
            set { bAllowSpaces = value; }
        }

        public ExtendedTextbox()
        {
            InitializeComponent();
        }

        private void ExtendedTextbox_KeyPress(object sender, KeyPressEventArgs e)
        {
            switch (tTextboxType)
            {
                case TypeOfTextbox.NumbersOnly:
                    #region Code for Numbers Only
                    if (this.Text.Length == 0 && bAllowNegatives && e.KeyChar == '-')
                        e.Handled = false;
                    else if (char.IsDigit(e.KeyChar))
                        e.Handled = false;
                    else if (e.KeyChar == '\b' && this.Text.Length > 0)
                    {
                        int LastChar = this.Text.Length - 1;
                        char CharToDelete = Convert.ToChar(this.Text.Substring(LastChar, 1));
                        if (char.IsPunctuation(CharToDelete))
                            bIsDecimalPlaced = false;
                        e.Handled = false;
                    }
                    else if (iNoOfDecimals > 0 && e.KeyChar == '.' && !bIsDecimalPlaced)
                    {
                        if (this.Text.Length == 0)
                        {
                            this.Text = "0.";
                            e.Handled = true;
                            this.SelectionStart = this.Text.Length;
                        }
                        else
                            e.Handled = false;

                        bIsDecimalPlaced = true;
                    }
                    else
                        e.Handled = true;
                    #endregion
                    break; // Exit case

                case TypeOfTextbox.LettersOnly:
                    #region Code for Letters Only
                    if (char.IsLetter(e.KeyChar))
                        e.Handled = false;
                    else if (e.KeyChar == '\b')
                        e.Handled = false;
                    else if (e.KeyChar == ' ' && bAllowSpaces)
                        e.Handled = false;
                    else if (e.KeyChar == '\r' && this.Multiline)
                        e.Handled = false;
                    else
                        e.Handled = true;
                    #endregion
                    break; // Exit case

                default:
                    #region Code for All
                    e.Handled = false;
                    #endregion
                    break;
            }
        }

        private void ExtendedTextbox_Leave(object sender, EventArgs e)
        {
            if (tTextboxType == TypeOfTextbox.NumbersOnly && iNoOfDecimals > 0)
            {
                double Number;
                Number = System.Math.Round(Convert.ToDouble(this.Text), iNoOfDecimals);
                string format = "{0:0.";
                for (int y = 0; y < iNoOfDecimals; y++)
                {
                    if (y == iNoOfDecimals - 1)
                        format = format + "0}";
                    else
                        format = format + "0";
                }
                this.Text = String.Format(format, Number);
            }
        }
    }
}
